<?php

/**
 * \file
 * Classe d'un formulaire.
 */

/**
 * Assistance à la génération de formulaires.
 */
namespace pilar\Forms /* \cond */ ; /* \endcond */
{

/**
 * Bloc de formulaire.
 *
 * \since 28/10/2008
 * \author Matthieu OVIEDO <matthieu.oviedo@gmail.com>
 */
class Form extends \pilar\Blocks\Block {

/**
 * Éléments.
 *
 * \since 30/11/2008
 */
protected $_atoms = array();


/**
 * Membres.
 *
 * \since 30/11/2008
 */
protected $_members = array();


/**
 * Status.
 *
 * A valeur dans \c 'unknown', \c 'valid', \c 'invalid'.
 *
 * \since 09/10/2008
 */
protected $_status = 'unknown';


protected function loadDefaultParams() {
 parent::loadDefaultParams();

 $this->params->define(array(
  'action' => '', // URL du script traitant les actions.
  'independent' => true, // Vrai si le formulaire est autonome.
 ));
}


/**
 * Inscrit un membre.
 *
 * \param $m Membre à inscrire.
 *
 * \since 30/11/2008
 */
private function joinMember(Member $m) {
 $this->_members[$m->get('name')] = $m;

 // Importation des dépendances du membre au bloc :
  foreach($m->precedingFiles() as $path) {
   $this->addContentPrecedingFile($path);
  }
}


/**
 * Membre en fonction de son nom.
 * 
 * \todo
 * Vérifier que le membre existe ?
 *
 * \param $m Nom du membre.
 * \return Membre correspondant au nom.
 *
 * \since 02/12/2008
 */
final public function member($m) {
 return $this->_members[$m];
}


/**
 * Accède de manière implicite à un membre en fonction de son nom.
 *
 * \param $m Nom du membre.
 * \return Membre correspondant au nom.
 *
 * \see member
 *
 * \since 02/12/2008
 */
final public function __get($m) {
 return $this->member($m);
}


/**
 * Ajoute un élément à la suite.
 *
 * \param $a Élément à ajouter.
 *
 * \since 30/11/2008
 */
final public function appendAtom(Atom $a) {
 $this->_atoms[] = $a;
 // Notification du changement de formulaire parent :
  $a->onParentFormChanged($this);
 // Inscription de tous les sous-membres de l'élément :
  foreach($a->subMembers() as $m) {
   $this->joinMember($m);
  }
}


/**
 * Ajoute un ou plusieurs éléments à la suite.
 *
 * \param $ Élements à ajouter.
 *
 * \since 01/12/2008
 */
final public function appendAtoms() {
 foreach(func_get_args() as $a) {
  if (is_array($a)) {
   foreach ($a as $atom) {
    $this->appendAtom($atom);
   }
  } else {
   $this->appendAtom($a);
  }
 }
}


/**
 * Charge le contenu des membres depuis le formulaire.
 *
 * Le status est mis à jour.
 *
 * \return Status du formulaire.
 *
 * \since 09/10/2008
 */
public function loadFromGui() {
 if($this->_status == 'unknown') {
  $this->_status = 'valid';
  foreach($this->_members as $m) {
   if($m->loadFromGui() == 'invalid') {
    $this->_status = 'invalid';
   }
  }
 }
 return $this->_status;
}


protected function specialHtmlHeader() { ?>
<?php if($this->get('independent')) { ?>
<form <?php if($this->get('action')!='') echo ('action="'.$this->get('action').'"'); ?> method="post" enctype="multipart/form-data">
<?php } ?>
<?php
}


protected function buildContentRoot($domDoc) {
 $domForm = $domDoc->createElement('form');

 foreach ($this->getRedirections() as $redirection) {
 	$redirection->append();
 }
 
 foreach($this->_atoms as $atom) {
  $domForm->appendChild($atom->domNode($domDoc));
 }

 return $domForm;
}


protected function specialHtmlFooter() { ?>
<?php if($this->get('independent')) { ?>
</form>
<?php } ?>
<script type="text/javascript">
 $(document).ready(function() {
<?php foreach($this->_members as $m) { $m->outputController(); } ?>
 });
</script>
<?php
}


} // Class.

} // Namespace.

?>

